package com.example.springmvc;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RequestMapping("/return")
//@RestController
@Controller
public class ReturnController {
    @RequestMapping("/index")
    public String returnIndex(){
        return "/Index.html";
        // 会发现直接返回这个数据了, 不是页面
        // 所以需要把 @RestController 这个注解 转换成 @Controller 这个注解
        // 这样就可以返回 页面了

        //那么这两个 注解 的区别是什么呢
        // 看源码

        //  如果这两个注解都不要的话, 会报错, 报 404 的错误
        // @Controller
        //  作用: 告诉 Spring 帮我们管理这个代码,我们后续访问后,才能访问到
        //  返回页面所需要的数据
        //  最后通过 ResponseBody 返回数据.
        // @RestController
        //  等于= Controller + ResponseBody

        //  所以 要想 返回数据就用 RestController
        //  要想 返回 页面 用 Controller.
        // 而且这两个注解不能修饰方法, 原理就是 源码里面的 Target 注解
        //  源码中的 第二个注解 Retention 表示生命周期
        //  第三个注解 Documented 表示文档
        // 而 RequestController

        // 有了注解才能交给Spring 管理

    }
    // 返回数据
    @ResponseBody
    @RequestMapping("/returnData")
    public String returnData() {
        return "返回视图所需要的数据";
        // 直接运行会报 404 错误
        // 因为当前的注解是 Controller
        // 所以在这个方法上加上 ResponseBody 注解

        // @ResponseBody 这个注解 可以修饰 类, 也可以修饰 方法
        // 当 修饰 类的时候, 表示 这个类下的所有 方法, 返回的均是数据
        // 当 修饰 方法 的时候, 表示 这个方法返回的是数据
        // 如果一个类当中的所有方法都要求返回数据, 那就把这个注解写道类外面
    }


    // 返回HTML代码片段
    @ResponseBody
    @RequestMapping("/returnHtml")
    public String returnHTML() {
        return "<h1>返回 html 片段 </h1>"; // 后端返回代码的时候 直接 使用就好了
        // 这个标签浏览器会自动帮我们识别
        // 那如果指向返回这样的一个数据
        // 那就需要把 < > 进行转义, 就可以显示原封不动的数据了

    }

    // 返回JSON
    @ResponseBody
    @RequestMapping("/returnJson")
    public Person returnJson() {
        Person person = new Person();
        person.setId(1);
        person.setName("zhangsan");
        person.setAge(14);
        return person;
    }

    // 这里面要注意
    // 当我们的接口 返回的是 String 时, content-Type 是 text/html
    // 当我们的接口 返回的是对象时, content-Type 自动设置为 application/json

    @ResponseBody
    @RequestMapping("/returnMap")
    public HashMap<String,String> returnMap() {
        Map<String,String> map = new HashMap<>();
        map.put("k1","v1");
        map.put("k2","v2");
        map.put("k3","v3");
        return (HashMap<String, String>) map;
    }
    // 如果返回的是 map 的时候 返回的也是 application/json

    // 至于怎么返回的,我们什么都不用做, 都会自动帮我们判断的
    // 当然 想要返回什么样子的 也是可以通过我们自己手动设置的



    // 设置状态码(指的是HTTP的状态码)
    // 可以通过 Servlet 来设置
    @ResponseBody
    @RequestMapping("/setStatus")
    public String setStatus(HttpServletResponse response) {
        response.setStatus(401); // 表示没有登录
        return "设置状态码";
        // 这里我们虽然设置 401 , 但是页面还是响应了这一段话
        // 抓包结果 显示已经设置成功了
        // 所以 设置状态码不影响影响页面的展示
    }

    // 设置 Content-Type

    @ResponseBody
    @RequestMapping(value = "/setCT",produces = "application/json;charset=utf8")
    public String setCT(HttpServletResponse response) {
        // 也可以添加一个Header
        response.setHeader("myHeader","myHeader");
        return "{'OK':1}";

        // 不写 produces = "application/json;charset=utf8" 的话 默认的是返回的 text/html
        // 写上这个的话 可以强行改变这个返回类型
        // 但也不是想怎么改就怎么改的
        // 也必须要返回的类型匹配
    }
    // 这个用的很少

}
